/**
 * 报表设计公司(2011)
 */
package com.reportgear.designer.pane.style;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import net.abbp.report.model.Cell;
import net.abbp.report.model.cell.style.BorderStyle;
import net.abbp.report.view.GridView;

import com.reportgear.core.swing.pane.base.JBasePane;
import net.abbp.swing.util.ImageUtils;
import com.reportgear.designer.swing.layout.VerticalFlowLayout;
import com.reportgear.designer.ui.base.ColorSelectionPane;
import com.reportgear.designer.ui.base.JLineComboBox;
import com.reportgear.designer.util.GUIConstants;
import com.reportgear.report.view.grid.selection.GridSelection;
import com.reportgear.report.view.grid.selection.Selection;
import com.reportgear.report.view.grid.util.GraphHelper;

/**
 * @version 1.0 2011-3-24
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since ANNCSR 2.0
 */
public class BorderStylePane extends JBasePane implements ICellStyle {

	private boolean insideMode = false;
	private BorderStyle cellBorderStyle;
	private BorderButton insideBorderButton;
	private BorderComponent borderComponent;
	private JToggleButton btnTop;
	private JToggleButton btnHorizental;
	private JToggleButton btnBottom;
	private JToggleButton btnLeft;
	private JToggleButton btnVertical;
	private JToggleButton btnRight;
	private JLineComboBox cbxLineStyle;
	private ColorSelectionPane pnlLineColor;
	ActionListener actionListener = new ActionListener() {

		public void actionPerformed(ActionEvent paramActionEvent) {
			fireStateChanged();
		}
	};

	public BorderStylePane() {
		initComponents();
	}

	private void initComponents() {
		cellBorderStyle = new BorderStyle();
		setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
		setLayout(new BorderLayout());
		JPanel contentPane = new JPanel();
		add(contentPane, BorderLayout.CENTER);
		contentPane.setLayout(new BorderLayout(4, 0));
		JPanel designPane = new JPanel();
		contentPane.add(designPane, BorderLayout.CENTER);
		designPane.setLayout(new BorderLayout(0, 2));
		designPane.setBorder(BorderFactory.createTitledBorder("预览:"));
		JPanel topTools = new JPanel(new FlowLayout(1, 16, 0));
		designPane.add(topTools, BorderLayout.NORTH);
		topTools.setBorder(BorderFactory.createEmptyBorder(0, 0, 4, 0));

		BorderButton btn0 = new BorderButton(new BorderButtonIcon(BorderStyle.NO_BORDERS));
		btn0.addActionListener(this.actionListener);
		btn0.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				borderComponent.setActiveBorders(BorderStyle.NO_BORDERS);
				// cellBorderStyle.setTopColor(Color.BLACK);
				cellBorderStyle.setTopStyle(0);
				// cellBorderStyle.setBottomColor(null);
				cellBorderStyle.setBottomStyle(0);
				// cellBorderStyle.setLeftColor(null);
				cellBorderStyle.setLeftStyle(0);
				// cellBorderStyle.setRightColor(null);
				cellBorderStyle.setRightStyle(0);
				// cellBorderStyle.setHorizentalColor(null);
				cellBorderStyle.setHorizentalStyle(0);
				// cellBorderStyle.setVerticalColor(null);
				cellBorderStyle.setVerticalStyle(0);
				refreshAllToggleButtons();
				borderComponent.repaint();
			}
		});
		topTools.add(createVerButtonPane(btn0, "否"));

		BorderButton btn1 = new BorderButton(new BorderButtonIcon(BorderStyle.EXTERNAL_BORDERS));
		btn1.addActionListener(this.actionListener);
		btn1.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				borderComponent.setActiveBorders(BorderStyle.EXTERNAL_BORDERS);
				cellBorderStyle.setTopColor(pnlLineColor.getColor());
				cellBorderStyle.setTopStyle(cbxLineStyle.getSelectedLineStyle());
				cellBorderStyle.setBottomColor(pnlLineColor.getColor());
				cellBorderStyle.setBottomStyle(cbxLineStyle.getSelectedLineStyle());
				cellBorderStyle.setLeftColor(pnlLineColor.getColor());
				cellBorderStyle.setLeftStyle(cbxLineStyle.getSelectedLineStyle());
				cellBorderStyle.setRightColor(pnlLineColor.getColor());
				cellBorderStyle.setRightStyle(cbxLineStyle.getSelectedLineStyle());
				refreshAllToggleButtons();
				borderComponent.repaint();
			}
		});
		topTools.add(createVerButtonPane(btn1, "外部"));

		this.insideBorderButton = new BorderButton(new BorderButtonIcon(BorderStyle.INSIDE_BORDERS));
		this.insideBorderButton.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent paramActionEvent) {
				borderComponent.setActiveBorders(BorderStyle.INSIDE_BORDERS);
				cellBorderStyle.setHorizentalColor(pnlLineColor.getColor());
				cellBorderStyle.setHorizentalStyle(cbxLineStyle.getSelectedLineStyle());
				cellBorderStyle.setVerticalColor(pnlLineColor.getColor());
				cellBorderStyle.setVerticalStyle(cbxLineStyle.getSelectedLineStyle());
				refreshAllToggleButtons();
				borderComponent.repaint();
			}
		});
		topTools.add(createVerButtonPane(this.insideBorderButton, "内部"));

		JPanel paneCenter = new JPanel();
		designPane.add(paneCenter, BorderLayout.CENTER);
		paneCenter.setLayout(new BorderLayout(0, 2));
		paneCenter.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 4));
		this.borderComponent = new BorderComponent();
		this.borderComponent.addBorderChangeListener(new ChangeListener() {

			public void stateChanged(ChangeEvent paramChangeEvent) {
				fireStateChanged();
			}
		});
		paneCenter.add(this.borderComponent, BorderLayout.CENTER);
		JPanel paneTHB = new JPanel();
		JPanel paneCornor = new JPanel();
		JPanel paneLVR = new JPanel();
		paneCenter.add(paneTHB, BorderLayout.WEST);
		JPanel paneBottom = new JPanel();
		paneBottom.setLayout(new BorderLayout());
		paneCenter.add(paneBottom, BorderLayout.SOUTH);
		paneBottom.add(paneLVR, BorderLayout.CENTER);
		paneBottom.add(paneCornor, BorderLayout.WEST);
		paneTHB.setLayout(new VerticalFlowLayout(1, 4, 16));
		this.btnTop = new ToggleButton(ImageUtils.readIcon("border/top.png"), BorderStyle.TOP_BORDER);
		this.btnHorizental = new ToggleButton(ImageUtils.readIcon("border/horizontal.png"),
				BorderStyle.HORIZONTAL_BORDER);
		this.btnBottom = new ToggleButton(ImageUtils.readIcon("border/bottom.png"),
				BorderStyle.BOTTOM_BORDER);
		this.btnLeft = new ToggleButton(ImageUtils.readIcon("border/left.png"), BorderStyle.LEFT_BORDER);
		this.btnVertical = new ToggleButton(ImageUtils.readIcon("border/vertical.png"),
				BorderStyle.VERTICAL_BORDER);
		this.btnRight = new ToggleButton(ImageUtils.readIcon("border/right.png"),
				BorderStyle.RIGHT_BORDER);
		paneTHB.add(this.btnTop);
		paneTHB.add(this.btnHorizental);
		paneTHB.add(this.btnBottom);
		paneLVR.setLayout(new FlowLayout(1, 42, 5));
		paneLVR.add(this.btnLeft);
		paneLVR.add(this.btnVertical);
		paneLVR.add(this.btnRight);
		paneCornor.setPreferredSize(new Dimension(paneTHB.getPreferredSize().width, paneLVR.getPreferredSize().height));

		JPanel paneLCContent = new JPanel();
		contentPane.add(paneLCContent, BorderLayout.EAST);
		paneLCContent.setLayout(new BorderLayout());
		paneLCContent.setBorder(BorderFactory.createTitledBorder("线条:"));
		JPanel paneLC = new JPanel();
		paneLCContent.add(paneLC, BorderLayout.NORTH);
		paneLC.setLayout(new GridLayout(4, 1, 2, 2));
		paneLC.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 2));
		paneLC.add(new JLabel("样式:"));
		this.cbxLineStyle = new JLineComboBox(GUIConstants.BorderlineStyleArray);
		paneLC.add(this.cbxLineStyle);
		paneLC.add(new JLabel("颜色:"));
		this.pnlLineColor = new ColorSelectionPane(100);
		paneLC.add(this.pnlLineColor);
		this.pnlLineColor.setColor(Color.BLACK);
	}

	public void addChangeListener(ChangeListener listener) {
		this.listenerList.add(ChangeListener.class, listener);
	}

	public void fireStateChanged() {
		ChangeEvent evt = new ChangeEvent(this);
		for (ChangeListener l : this.listenerList.getListeners(ChangeListener.class)) {
			l.stateChanged(evt);
		}
	}

	private JPanel createVerButtonPane(JComponent c, String caption) {
		JPanel pane = new JPanel();
		pane.setLayout(new VerticalFlowLayout(1, 2, 2));
		pane.add(c);
		pane.add(new JLabel(caption));
		return pane;
	}

	private void refreshAllToggleButtons() {
		this.btnTop.setSelected(this.cellBorderStyle.getTopStyle() != 0);
		this.btnHorizental.setSelected(this.cellBorderStyle.getHorizentalStyle() != 0);
		this.btnBottom.setSelected(this.cellBorderStyle.getBottomStyle() != 0);
		this.btnLeft.setSelected(this.cellBorderStyle.getLeftStyle() != 0);
		this.btnVertical.setSelected(this.cellBorderStyle.getVerticalStyle() != 0);
		this.btnRight.setSelected(this.cellBorderStyle.getRightStyle() != 0);
	}

	public BorderStyle getCellBorderStyle() {
		return this.cellBorderStyle;
	}

	public void setCellBorderStyle(BorderStyle cellBorderStyle) {
		this.cellBorderStyle = cellBorderStyle;
	}

	public void populate(BorderStyle border, boolean insideMode) {
		BorderStyle cellBorder = new BorderStyle();

		cellBorder.setTopStyle(border.getTopStyle());
		cellBorder.setTopColor(border.getTopColor());
		cellBorder.setLeftStyle(border.getLeftStyle());
		cellBorder.setLeftColor(border.getLeftColor());
		cellBorder.setBottomStyle(border.getBottomStyle());
		cellBorder.setBottomColor(border.getBottomColor());
		cellBorder.setRightStyle(border.getRightStyle());
		cellBorder.setRightColor(border.getRightColor());

		populate(cellBorder, insideMode, border.getTopStyle(), border.getTopColor());
	}

	public void populate(BorderStyle border, boolean insideMode, int selectedLineStyle, Color color) {
		this.cellBorderStyle = border;

		this.insideMode = insideMode;
		this.cbxLineStyle.setSelectedLineStyle(selectedLineStyle);
		this.pnlLineColor.setColor(color);
		this.insideBorderButton.setEnabled(this.insideMode);
		this.btnHorizental.setEnabled(this.insideMode);
		this.btnVertical.setEnabled(this.insideMode);
		this.borderComponent.repaint();

		refreshAllToggleButtons();
	}

	public BorderStyle update() {
		return this.cellBorderStyle;
	}

	public void populateCellStyle(GridView workSheet) {
		BorderStyle border = workSheet.getActiveCellStyle().getBorderStyle();

		if (border != null) {
			Selection rect = workSheet.getGridSelection().getLastCellSelection();
			if ((rect.getColumSpan() > 1) || (rect.getRowSpan() > 1)) {
				populate(border, true);
			} else {
				populate(border, false);
			}
		}
	}

	public void updateCellStyle(GridView worksheet) {
		BorderStyle border = update();

		if (worksheet.getActiveCellStyle().getBorderStyle().equals(border)) {
			return;
		}

		GridSelection gridSel = worksheet.getGridSelection();
		for (Selection rect : gridSel.getCellSelectionList()) {
			if ((rect.getColumSpan() == 1) && (rect.getRowSpan() == 1)) {
				Cell cell = worksheet.getReportModel().getCell(rect);
				cell.setStyle(cell.getStyle().deriveBorder(border));
			} else {
				for (int column = rect.getColumn(), len = rect.getColumn() + rect.getColumSpan(); column < len; column++) {
					int leftStyle = border.getVerticalStyle();
					Color leftColor = border.getVerticalColor();
					int rightStyle = border.getVerticalStyle();
					Color rightColor = border.getVerticalColor();

					if (column == rect.getColumn()) {
						leftStyle = border.getLeftStyle();
						leftColor = border.getLeftColor();
					}

					if (column == rect.getColumn() + rect.getColumSpan() - 1) {
						rightStyle = border.getRightStyle();
						rightColor = border.getRightColor();
					}
					for (int row = rect.getRow(); row < rect.getRow() + rect.getRowSpan(); row++) {
						int topStyle = border.getHorizentalStyle();
						Color topColor = border.getHorizentalColor();
						int bottomStyle = border.getHorizentalStyle();
						Color bottomColor = border.getHorizentalColor();

						if (row == rect.getRow()) {
							topStyle = border.getTopStyle();
							topColor = border.getTopColor();
						}

						if (row == rect.getRow() + rect.getRowSpan() - 1) {
							bottomStyle = border.getBottomStyle();
							bottomColor = border.getBottomColor();
						}

						Cell cell = worksheet.getReportModel().getCell(column, row);
						cell.setStyle(cell.getStyle().deriveBorder(topStyle, topColor, leftStyle, leftColor,
								bottomStyle, bottomColor, rightStyle, rightColor));
					}
				}
			}
		}
	}

	private class BorderComponent extends JComponent {

		private boolean topActive;
		private boolean leftActive;
		private boolean bottomActive;
		private boolean rightActive;
		private boolean verticalActive;
		private boolean horizontalActive;

		private BorderComponent() {
			this.topActive = false;
			this.leftActive = false;
			this.bottomActive = false;
			this.rightActive = false;
			this.verticalActive = false;
			this.horizontalActive = false;
			setOpaque(true);
		}

		@Override
		public void paint(Graphics g) {
			int[] pointLeft;
			int[] pointRight;
			g.setColor(Color.white);
			g.fillRect(0, 0, getWidth() - 1, getHeight() - 1);
			g.setColor(Color.black);
			g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
			if (this.topActive) {
				pointLeft = new int[] { 3, 3, 10 };
				pointRight = new int[] { 7, 13, 10 };
				g.fillPolygon(pointLeft, pointRight, 3);
			} else {
				g.drawLine(3, 10, 10, 10);
			}
			if (this.leftActive) {
				pointLeft = new int[] { 7, 13, 10 };
				pointRight = new int[] { 3, 3, 10 };
				g.fillPolygon(pointLeft, pointRight, 3);
			} else {
				g.drawLine(10, 3, 10, 10);
			}
			if (insideMode) {
				g.drawLine(getWidth() / 2 - 3, 10, getWidth() / 2 + 3, 10);
				if (this.verticalActive) {
					pointLeft = new int[] { getWidth() / 2 - 3, getWidth() / 2 + 3, getWidth() / 2 };
					pointRight = new int[] { 3, 3, 10 };
					g.fillPolygon(pointLeft, pointRight, 3);
				} else {
					g.drawLine(getWidth() / 2, 3, getWidth() / 2, 10);
				}
			}
			if (this.topActive) {
				pointLeft = new int[] { getWidth() - 3, getWidth() - 11, getWidth() - 3 };
				pointRight = new int[] { 7, 10, 13 };
				g.fillPolygon(pointLeft, pointRight, 3);
			} else {
				g.drawLine(getWidth() - 11, 10, getWidth() - 4, 10);
			}
			if (this.rightActive) {
				pointLeft = new int[] { getWidth() - 14, getWidth() - 8, getWidth() - 11 };
				pointRight = new int[] { 3, 3, 10 };
				g.fillPolygon(pointLeft, pointRight, 3);
			} else {
				g.drawLine(getWidth() - 11, 3, getWidth() - 11, 10);
			}
			if (insideMode) {
				g.drawLine(getWidth() - 11, getHeight() / 2 - 3, getWidth() - 11, getHeight() / 2 + 3);
				if (this.horizontalActive) {
					pointLeft = new int[] { getWidth() - 3, getWidth() - 11, getWidth() - 3 };
					pointRight = new int[] { getHeight() / 2 - 3, getHeight() / 2, getHeight() / 2 + 3 };
					g.fillPolygon(pointLeft, pointRight, 3);
				} else {
					g.drawLine(getWidth() - 11, getHeight() / 2, getWidth() - 4, getHeight() / 2);
				}
			}
			if (this.bottomActive) {
				pointLeft = new int[] { 3, 3, 10 };
				pointRight = new int[] { getHeight() - 14, getHeight() - 8, getHeight() - 11 };
				g.fillPolygon(pointLeft, pointRight, 3);
			} else {
				g.drawLine(3, getHeight() - 11, 10, getHeight() - 11);
			}
			if (this.leftActive) {
				pointLeft = new int[] { 7, 13, 10 };
				pointRight = new int[] { getHeight() - 3, getHeight() - 3, getHeight() - 11 };
				g.fillPolygon(pointLeft, pointRight, 3);
			} else {
				g.drawLine(10, getHeight() - 11, 10, getHeight() - 4);
			}
			if (insideMode) {
				g.drawLine(10, getHeight() / 2 - 3, 10, getHeight() / 2 + 3);
				if (this.horizontalActive) {
					pointLeft = new int[] { 3, 3, 10 };
					pointRight = new int[] { getHeight() / 2 - 3, getHeight() / 2 + 3, getHeight() / 2 };
					g.fillPolygon(pointLeft, pointRight, 3);
				} else {
					g.drawLine(3, getHeight() / 2, 10, getHeight() / 2);
				}
			}
			if (this.rightActive) {
				pointLeft = new int[] { getWidth() - 14, getWidth() - 8, getWidth() - 11 };
				pointRight = new int[] { getHeight() - 3, getHeight() - 3, getHeight() - 11 };
				g.fillPolygon(pointLeft, pointRight, 3);
			} else {
				g.drawLine(getWidth() - 11, getHeight() - 11, getWidth() - 11, getHeight() - 4);
			}
			if (this.bottomActive) {
				pointLeft = new int[] { getWidth() - 3, getWidth() - 11, getWidth() - 3 };
				pointRight = new int[] { getHeight() - 14, getHeight() - 11, getHeight() - 8 };
				g.fillPolygon(pointLeft, pointRight, 3);
			} else {
				g.drawLine(getWidth() - 11, getHeight() - 11, getWidth() - 4, getHeight() - 11);
			}
			if (insideMode) {
				g.drawLine(getWidth() / 2 - 3, getHeight() - 11, getWidth() / 2 + 3, getHeight() - 11);
				if (this.verticalActive) {
					pointLeft = new int[] { getWidth() / 2 - 3, getWidth() / 2 + 3, getWidth() / 2 };
					pointRight = new int[] { getHeight() - 3, getHeight() - 3, getHeight() - 11 };
					g.fillPolygon(pointLeft, pointRight, 3);
				} else {
					g.drawLine(getWidth() / 2, getHeight() - 11, getWidth() / 2, getHeight() - 4);
				}
			}
			if (insideMode) {
				int gap = 4;
				int w = getWidth() / 2 - 20 - gap;
				int h = getHeight() / 2 - 20 - gap;
				g.setColor(Color.lightGray);
				g.fillRect(20, 20, w, h);
				g.setColor(Color.lightGray);
				g.fillRect(getWidth() / 2 + gap + 1, 20, w, h);
				g.setColor(Color.lightGray);
				g.fillRect(20, getHeight() / 2 + gap + 1, w, h);
				g.setColor(Color.lightGray);
				g.fillRect(getWidth() / 2 + gap + 1, getHeight() / 2 + gap + 1, w, h);
			} else {
				g.setColor(Color.lightGray);
				g.fillRect(20, 20, getWidth() - 40, getHeight() - 40);
			}
			updateBorders(g);
		}

		public void addBorderChangeListener(ChangeListener paramChangeListener) {
		}

		public void fireBorderStateChanged() {
		}

		private void updateBorders(Graphics g) {
			Graphics2D g2 = (Graphics2D) g;
			pnlLineColor.getColor();
			if ((cellBorderStyle.getTopColor() != null) && (cellBorderStyle.getTopStyle() != 0)) {
				g2.setColor(cellBorderStyle.getTopColor());
				GraphHelper.drawLine(g2, 15.0D, 15.0D, getWidth() - 15, 15.0D, cellBorderStyle.getTopStyle());
			}
			if ((cellBorderStyle.getLeftColor() != null) && (cellBorderStyle.getLeftStyle() != 0)) {
				g2.setColor(cellBorderStyle.getLeftColor());
				GraphHelper.drawLine(g2, 15.0D, 15.0D, 15.0D, getHeight() - 15, cellBorderStyle.getLeftStyle());
			}
			if ((cellBorderStyle.getBottomColor() != null) && (cellBorderStyle.getBottomStyle() != 0)) {
				g2.setColor(cellBorderStyle.getBottomColor());
				GraphHelper.drawLine(g2, 15.0D, getHeight() - 15, getWidth() - 15, getHeight() - 15, cellBorderStyle
						.getBottomStyle());
			}
			if ((cellBorderStyle.getRightColor() != null) && (cellBorderStyle.getRightStyle() != 0)) {
				g2.setColor(cellBorderStyle.getRightColor());
				GraphHelper.drawLine(g2, getWidth() - 15, 15.0D, getWidth() - 15, getHeight() - 15, cellBorderStyle
						.getRightStyle());
			}
			if ((cellBorderStyle.getVerticalColor() != null) && (cellBorderStyle.getVerticalStyle() != 0)) {
				g2.setColor(cellBorderStyle.getVerticalColor());
				GraphHelper.drawLine(g2, getWidth() / 2, 16.0D, getWidth() / 2, getHeight() - 16, cellBorderStyle
						.getVerticalStyle());
			}
			if ((cellBorderStyle.getHorizentalColor() != null) && (cellBorderStyle.getHorizentalStyle() != 0)) {
				g2.setColor(cellBorderStyle.getHorizentalColor());
				GraphHelper.drawLine(g2, 16.0D, getHeight() / 2, getWidth() - 16, getHeight() / 2, cellBorderStyle
						.getHorizentalStyle());
			}
			fireBorderStateChanged();
		}

		private void setActiveBorders(int borderType) {
			switch (borderType) {
			case BorderStyle.NO_BORDERS:
				this.topActive = (this.leftActive = this.bottomActive = this.rightActive = this.verticalActive = this.horizontalActive = false);
				break;
			case BorderStyle.EXTERNAL_BORDERS:
				this.topActive = (this.leftActive = this.bottomActive = this.rightActive = true);
				this.verticalActive = (this.horizontalActive = false);
				break;
			case BorderStyle.INSIDE_BORDERS:
				this.topActive = (this.leftActive = this.bottomActive = this.rightActive = false);
				this.verticalActive = (this.horizontalActive = true);
				break;
			case BorderStyle.TOP_BORDER:
				this.topActive = true;
				this.leftActive = (this.bottomActive = this.rightActive = this.verticalActive = this.horizontalActive = false);
				break;
			case BorderStyle.LEFT_BORDER:
				this.leftActive = true;
				this.topActive = (this.bottomActive = this.rightActive = this.verticalActive = this.horizontalActive = false);
				break;
			case BorderStyle.BOTTOM_BORDER:
				this.bottomActive = true;
				this.topActive = (this.leftActive = this.rightActive = this.verticalActive = this.horizontalActive = false);
				break;
			case BorderStyle.RIGHT_BORDER:
				this.rightActive = true;
				this.topActive = (this.leftActive = this.bottomActive = this.verticalActive = this.horizontalActive = false);
				break;
			case BorderStyle.VERTICAL_BORDER:
				this.verticalActive = true;
				this.topActive = (this.leftActive = this.bottomActive = this.rightActive = this.horizontalActive = false);
				break;
			case BorderStyle.HORIZONTAL_BORDER:
				this.horizontalActive = true;
				this.topActive = (this.leftActive = this.bottomActive = this.rightActive = this.verticalActive = false);
			}
		}
	}

	private class BorderButtonIcon implements Icon {

		private int display;

		private BorderButtonIcon(int display) {
			this.display = display;
		}

		public int getIconWidth() {
			return 32;
		}

		public int getIconHeight() {
			return 32;
		}

		public void paintIcon(Component c, Graphics g, int x, int y) {
			if (this.display == BorderStyle.EXTERNAL_BORDERS) {
				g.setColor(Color.black);
				g.drawRect(3, 3, getIconWidth() - 7, getIconHeight() - 7);
			} else {
				if (this.display != BorderStyle.INSIDE_BORDERS) {
					return;
				}
				g.setColor(Color.black);
				g.drawLine(getIconWidth() / 2, 3, getIconWidth() / 2, getIconHeight() - 4);
				g.drawLine(3, getIconHeight() / 2, getIconWidth() - 4, getIconHeight() / 2);
				g.setColor(Color.lightGray);
				g.drawRect(3, 3, getIconWidth() - 7, getIconHeight() - 7);
			}
		}
	}

	private class BorderButton extends JButton {

		private BorderButton(Icon icon) {
			super(icon);

			setPreferredSize(new Dimension(32, 32));
			setFocusPainted(false);
		}
	}

	private class ToggleButton extends JToggleButton implements ActionListener {

		private int borderType = 0;

		public ToggleButton(Icon icon, int style) {
			super(icon);
			this.borderType = style;
			setPreferredSize(new Dimension(32, 32));
			addActionListener(this);
		}

		public void actionPerformed(ActionEvent e) {
			if (isSelected()) {
				borderComponent.setActiveBorders(this.borderType);
			} else {
				borderComponent.setActiveBorders(BorderStyle.NO_BORDERS);
			}

			switch (this.borderType) {
			case BorderStyle.TOP_BORDER:
				if (isSelected()) {
					if ((cellBorderStyle.getTopStyle() == cbxLineStyle.getSelectedLineStyle())
							&& (cellBorderStyle.getTopColor() == pnlLineColor.getColor())) {
						cellBorderStyle.setTopStyle(0);
						cellBorderStyle.setTopColor(Color.WHITE);
					} else {
						cellBorderStyle.setTopColor(pnlLineColor.getColor());
						cellBorderStyle.setTopStyle(cbxLineStyle.getSelectedLineStyle());
					}
				} else if ((cellBorderStyle.getTopStyle() == 0) && (cellBorderStyle.getTopColor() == Color.WHITE)) {
					cellBorderStyle.setTopStyle(cbxLineStyle.getSelectedLineStyle());
					cellBorderStyle.setTopColor(pnlLineColor.getColor());
				} else {
					cellBorderStyle.setTopColor(Color.BLACK);
					cellBorderStyle.setTopStyle(0);
				}
				break;
			case BorderStyle.HORIZONTAL_BORDER:
				if (isSelected()) {
					if ((cellBorderStyle.getHorizentalStyle() == cbxLineStyle.getSelectedLineStyle())
							&& (cellBorderStyle.getHorizentalColor() == pnlLineColor.getColor())) {
						cellBorderStyle.setHorizentalStyle(0);
						cellBorderStyle.setHorizentalColor(Color.WHITE);
					} else {
						cellBorderStyle.setHorizentalColor(pnlLineColor.getColor());
						cellBorderStyle.setHorizentalStyle(cbxLineStyle.getSelectedLineStyle());
					}
				} else if ((cellBorderStyle.getHorizentalStyle() == 0)
						&& (cellBorderStyle.getHorizentalColor() == Color.WHITE)) {
					cellBorderStyle.setHorizentalStyle(cbxLineStyle.getSelectedLineStyle());
					cellBorderStyle.setHorizentalColor(pnlLineColor.getColor());
				} else {
					cellBorderStyle.setHorizentalColor(Color.BLACK);
					cellBorderStyle.setHorizentalStyle(0);
				}
				break;
			case BorderStyle.BOTTOM_BORDER:
				if (isSelected()) {
					if ((cellBorderStyle.getBottomStyle() == cbxLineStyle.getSelectedLineStyle())
							&& (cellBorderStyle.getBottomColor() == pnlLineColor.getColor())) {
						cellBorderStyle.setBottomStyle(0);
						cellBorderStyle.setBottomColor(Color.WHITE);
					} else {
						cellBorderStyle.setBottomColor(pnlLineColor.getColor());
						cellBorderStyle.setBottomStyle(cbxLineStyle.getSelectedLineStyle());
					}
				} else if ((cellBorderStyle.getBottomStyle() == 0) && (cellBorderStyle.getBottomColor() == Color.WHITE)) {
					cellBorderStyle.setBottomStyle(cbxLineStyle.getSelectedLineStyle());
					cellBorderStyle.setBottomColor(pnlLineColor.getColor());
				} else {
					cellBorderStyle.setBottomColor(Color.BLACK);
					cellBorderStyle.setBottomStyle(0);
				}
				break;
			case BorderStyle.LEFT_BORDER:
				if (isSelected()) {
					if ((cellBorderStyle.getLeftStyle() == cbxLineStyle.getSelectedLineStyle())
							&& (cellBorderStyle.getLeftColor() == pnlLineColor.getColor())) {
						cellBorderStyle.setLeftStyle(0);
						cellBorderStyle.setLeftColor(Color.WHITE);
					} else {
						cellBorderStyle.setLeftColor(pnlLineColor.getColor());
						cellBorderStyle.setLeftStyle(cbxLineStyle.getSelectedLineStyle());
					}
				} else if ((cellBorderStyle.getLeftStyle() == 0) && (cellBorderStyle.getLeftColor() == Color.WHITE)) {
					cellBorderStyle.setLeftStyle(cbxLineStyle.getSelectedLineStyle());
					cellBorderStyle.setLeftColor(pnlLineColor.getColor());
				} else {
					cellBorderStyle.setLeftColor(Color.BLACK);
					cellBorderStyle.setLeftStyle(0);
				}
				break;
			case BorderStyle.VERTICAL_BORDER:
				if (isSelected()) {
					if ((cellBorderStyle.getVerticalStyle() == cbxLineStyle.getSelectedLineStyle())
							&& (cellBorderStyle.getVerticalColor() == pnlLineColor.getColor())) {
						cellBorderStyle.setVerticalStyle(0);
						cellBorderStyle.setVerticalColor(Color.WHITE);
					} else {
						cellBorderStyle.setVerticalColor(pnlLineColor.getColor());
						cellBorderStyle.setVerticalStyle(cbxLineStyle.getSelectedLineStyle());
					}
				} else if ((cellBorderStyle.getVerticalStyle() == 0)
						&& (cellBorderStyle.getVerticalColor() == Color.WHITE)) {
					cellBorderStyle.setVerticalStyle(cbxLineStyle.getSelectedLineStyle());
					cellBorderStyle.setVerticalColor(pnlLineColor.getColor());
				} else {
					cellBorderStyle.setVerticalColor(Color.BLACK);
					cellBorderStyle.setVerticalStyle(0);
				}
				break;
			case BorderStyle.RIGHT_BORDER:
				if (isSelected()) {
					if ((cellBorderStyle.getRightStyle() == cbxLineStyle.getSelectedLineStyle())
							&& (cellBorderStyle.getRightColor() == pnlLineColor.getColor())) {
						cellBorderStyle.setRightStyle(0);
						cellBorderStyle.setRightColor(Color.WHITE);
					} else {
						cellBorderStyle.setRightColor(pnlLineColor.getColor());
						cellBorderStyle.setRightStyle(cbxLineStyle.getSelectedLineStyle());
					}
				} else if ((cellBorderStyle.getRightStyle() == 0) && (cellBorderStyle.getRightColor() == Color.WHITE)) {
					cellBorderStyle.setRightStyle(cbxLineStyle.getSelectedLineStyle());
					cellBorderStyle.setRightColor(pnlLineColor.getColor());
				} else {
					cellBorderStyle.setRightColor(Color.BLACK);
					cellBorderStyle.setRightStyle(0);
				}
			}
			borderComponent.repaint();
		}
	}
}